/*
 * @(#)DialogAlarm.java
 * 1.0, 2013-01-24
 */
package de.hdm.gruppenkalender.team04.gui;

import de.hdm.gruppenkalender.team04.data.Alarm;
import de.hdm.gruppenkalender.team04.data.Kalender;
import de.hdm.gruppenkalender.team04.data.Kategorie;
import de.hdm.gruppenkalender.team04.data.Person;
import de.hdm.gruppenkalender.team04.data.Termin;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.rmi.RemoteException;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.SpinnerDateModel;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

/**
 * Aufbau des Alarm Dialog mit den diversen Elementen.
 *
 * @author Mathias Bendel (mb167)
 * @author Björn Fichnter (bf023)
 * @author Stefan Hettich (sh176)
 * @author René Kugel (rk044)
 * @author Mark Leonberger (ml072)
 * @author Marta Przybylski (mp070)
 *
 * @version 1.0, 2013-01-24
 *
 */
public class DialogAlarm extends JDialog {

    // Alarm der gestzt wird, wenn Bearbeiten-Fenster geöffnet wird.
    Alarm alarm;
    JTextField txtTitel;
    JButton buttonSpeichern;
    JSpinner spnStart;
    JComboBox cbxKategorie;
    JComboBox cbxErsteller;
    JComboBox cbxKalender;
    JComboBox cbxGueltigFuer;
    JCheckBox chbGueltigFuer;
    HashMap<String, Kategorie> hashMapKategorie;
    HashMap<String, Person> hashMapErsteller;
    HashMap<String, Kalender> hashMapKalender;
    HashMap<String, Termin> hashMapGueltigFuer;
    HauptFenster hauptFenster;
    InterfaceClient ic = InterfaceClient.interfaceClient();
    // Aktueller System-Nutzer, ist null, falls Administrator angemeldet.
    Person aktuellerNutzer;
    private final static String STR_TITEL =
            "Bitte geben Sie den Titel ein.";

    /**
     * Konstruktor, der das aufrufende Hauptfenster übergibt.
     *
     * @param hf
     */
    public DialogAlarm(HauptFenster hf) {
        this(hf, null);
    }

    /**
     * Konstruktor, der das aufrufende Hauptfenster und den zu
     * bearbeitenden Alarm übergibt.
     * <p>
     * Der aktuelle Nutzer wird aus dem HauptFenster ausgelesen und
     * das Erstellen der Elemente wird angestoßen.
     *
     * @param hf
     * @param alarm
     */
    public DialogAlarm(HauptFenster hf, Alarm alarm) {
        super(hf, "", true);
        this.hauptFenster = hf;
        this.aktuellerNutzer = hauptFenster.getAktuellerNutzer();
        this.alarm = alarm;
        this.erstelleElemente();
    }

    /*
     * erstellt alle Elemente für den Dialog Alarm
     */
    public void erstelleElemente() {
        if (alarm == null) {
            this.setTitle("Alarm anlegen");
        } else {
            try {
                this.setTitle("Alarm '" + alarm.getTitel() + "' bearbeiten");
            } catch (RemoteException ex) {
                Logger.getLogger(DialogAlarm.class.getName()).log(Level.SEVERE,
                        null, ex);
                this.setTitle("Alarm bearbeiten");
            }
        }

        JPanel hauptPanel = erstelleHauptPanel();
        if (hauptPanel != null) {
            this.add(hauptPanel);

            this.setLocation(50, 50);
            this.setResizable(false);

            this.pack();
            this.setVisible(true);
        }
    }

    /**
     *
     * füllt das Hauptpanel mit allen GUI-Elementen
     * und befüllt die GUI-Elemente
     *
     * @return  JPanel  hauptPanel
     */
    public JPanel erstelleHauptPanel() {
        JPanel hauptPanel = new JPanel();

        // Dient zum setzen der Werte in den ComboBoxen.
        String ausgewaehlt = "";

        // GridBagLayout mit Abstand zwischen den Elementen.
        hauptPanel.setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.HORIZONTAL;
        c.anchor = GridBagConstraints.LINE_START;
        c.insets = new Insets(5, 5, 5, 5);

        // Abstand nach außen erzeugen.
        hauptPanel.setBorder(new EmptyBorder(10, 10, 10, 10));

        /**
         * TextFeld und Label für Titel.
         */
        c.gridx = 0;
        c.gridy = 0;
        c.gridwidth = 1;
        hauptPanel.add(new JLabel("Titel:", JLabel.RIGHT), c);

        txtTitel = erstelleTextFeld(STR_TITEL);
        c.gridx = 1;
        c.gridy = 0;
        c.gridwidth = 2;
        hauptPanel.add(txtTitel, c);

        /**
         * JSpinner und Label für Startdatum.
         */
        c.gridx = 0;
        c.gridy = 1;
        c.gridwidth = 1;
        hauptPanel.add(new JLabel("Startdatum:", JLabel.RIGHT), c);

        spnStart = erstelleDateSpinner();
        c.gridx = 1;
        c.gridy = 1;
        c.gridwidth = 2;
        hauptPanel.add(spnStart, c);

        /**
         * Combo-Box und Label für Kategorie.
         */
        c.gridx = 0;
        c.gridy = 2;
        c.gridwidth = 1;
        hauptPanel.add(new JLabel("Kategorie:", JLabel.RIGHT), c);

        ausgewaehlt = "";
        Vector<Kategorie> kategorien = ic.ermittleAlleKategorien();
        Vector<String> strKategorie = new Vector<String>();
        hashMapKategorie = new HashMap<String, Kategorie>();

        for (Kategorie kategorie : kategorien) {
            String name = "";
            try {
                name = kategorie.ermittleIdentifikationsName();
                if (alarm != null) {
                    if (kategorie.getKategorieId() == alarm.getKategorieId()) {
                        ausgewaehlt = name;
                    }
                }
            } catch (RemoteException ex) {
                Logger.getLogger(DialogAlarm.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
            strKategorie.add(name);
            hashMapKategorie.put(name, kategorie);
        }
        cbxKategorie = new JComboBox(strKategorie);

        c.gridx = 1;
        c.gridy = 2;
        c.gridwidth = 2;
        hauptPanel.add(cbxKategorie, c);

        if (alarm != null) {
            cbxKategorie.setSelectedItem(ausgewaehlt);
        }

        /**
         * Wenn Administrator angemeldet ist, muss ein Ersteller gewählt werden.
         */
        int gridLayoutParam = 0;
        if (aktuellerNutzer == null) {
            /**
             * ComboBox und Label für Ersteller.
             */
            gridLayoutParam = 1;
            c.gridx = 0;
            c.gridy = 3;
            c.gridwidth = 1;
            hauptPanel.add(new JLabel("Ersteller:", JLabel.RIGHT), c);

            ausgewaehlt = "";
            Vector<Person> erstellers = ic.ermittleAllePersonen();
            if (erstellers.size() < 1) {
                // Wenn es keine Personen gibt.
                JOptionPane.showMessageDialog(hauptFenster,
                        "Es existieren keine Personen.\n Erstellen Sie " +
                        "zunächst eine Person.",
                        "Fehler im Datenbestand",
                        JOptionPane.ERROR_MESSAGE);
                return null;
            }
            Vector<String> strErsteller = new Vector<String>();
            hashMapErsteller = new HashMap<String, Person>();
            for (Person ersteller : erstellers) {
                String name = "";
                try {
                    name = ersteller.ermittleIdentifikationsName();
                    if (alarm != null) {
                        if (ersteller.getPersonId() == alarm.getErstellerId()) {
                            ausgewaehlt = name;
                        }
                    }
                } catch (RemoteException ex) {
                    Logger.getLogger(DialogTermin.class.getName()).
                            log(Level.SEVERE, null, ex);
                }
                strErsteller.add(name);
                hashMapErsteller.put(name, ersteller);
            }
            cbxErsteller = new JComboBox(strErsteller);
            c.gridx = 1;
            c.gridy = 3;
            c.gridwidth = 2;
            hauptPanel.add(cbxErsteller, c);

            if (alarm != null) {
                cbxErsteller.setSelectedItem(ausgewaehlt);
            }
        }

        /**
         * ComboBox und Label für Kalender.
         */
        c.gridx = 0;
        c.gridy = 3 + gridLayoutParam;
        c.gridwidth = 1;
        hauptPanel.add(new JLabel("Kalender:", JLabel.RIGHT), c);

        ausgewaehlt = "";
        Vector<Kalender> kalenders = new Vector<Kalender>();
        if (aktuellerNutzer == null) {
            kalenders = ic.ermittleAlleKalender();
        } else {
            // Nur die Kalender von aktueller Nutzer
            kalenders = ic.ermittleAlleKalenderVon(aktuellerNutzer);
        }
        Vector<String> strKalender = new Vector<String>();
        hashMapKalender = new HashMap<String, Kalender>();
        for (Kalender kalender : kalenders) {
            try {
                String name = kalender.ermittleIdentifikationsName();
                if (alarm != null) {
                    if (kalender.getKalenderId() == alarm.getKalenderId()) {
                        ausgewaehlt = name;
                    }
                }
                strKalender.add(name);
                hashMapKalender.put(name, kalender);
            } catch (RemoteException ex) {
                Logger.getLogger(DialogTermin.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
        }
        cbxKalender = new JComboBox(strKalender);
        c.gridx = 1;
        c.gridy = 3 + gridLayoutParam;
        c.gridwidth = 2;
        hauptPanel.add(cbxKalender, c);

        if (alarm != null) {
            cbxKalender.setSelectedItem(ausgewaehlt);
        }

        /**
         * ComboBox, CheckBox und Label für Gültig-Für-Termin.
         */
        c.gridx = 0;
        c.gridy = 4 + gridLayoutParam;
        c.gridwidth = 1;
        hauptPanel.add(new JLabel("Gültig für:", JLabel.RIGHT), c);

        ausgewaehlt = "";
        Vector<Termin> termine = new Vector<Termin>();
        if (aktuellerNutzer == null) {
            termine = ic.ermittleAlleTermine();
        } else {
            termine = ic.ermittleAlleTermineVon(aktuellerNutzer);
        }

        Vector<String> strTermine = new Vector<String>();
        hashMapGueltigFuer = new HashMap<String, Termin>();

        for (Termin termin : termine) {
            String name = "";
            try {
                boolean istWiederholung = false;
                if (ic.istWiederholung(termin.getId())) {
                    istWiederholung = true;
                }
                name = termin.ermittleIdentifikationsName(istWiederholung);
                if (alarm != null) {
                    if (termin.getId() == alarm.getGueltigFuerId()) {
                        ausgewaehlt = name;
                    }
                }
            } catch (RemoteException ex) {
                Logger.getLogger(DialogAlarm.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
            strTermine.add(name);
            hashMapGueltigFuer.put(name, termin);
        }
        cbxGueltigFuer = new JComboBox(strTermine);

        c.gridx = 1;
        c.gridy = 4 + gridLayoutParam;
        c.gridwidth = 1;
        hauptPanel.add(cbxGueltigFuer, c);

        chbGueltigFuer = new JCheckBox("Termin zuordnen");
        chbGueltigFuer.addChangeListener(new ChangeListener() {

            public void stateChanged(ChangeEvent e) {
                if (((JCheckBox) e.getSource()).isSelected()) {
                    cbxGueltigFuer.setEnabled(true);
                } else {
                    cbxGueltigFuer.setEnabled(false);
                }
            }
        });

        c.gridx = 2;
        c.gridy = 4 + gridLayoutParam;
        c.gridwidth = 1;
        hauptPanel.add(chbGueltigFuer, c);

        if (termine.size() > 0) {
            if (alarm != null) {
                if (ausgewaehlt.equals("")) {
                    chbGueltigFuer.setSelected(false);
                    cbxGueltigFuer.setEnabled(false);
                } else {
                    chbGueltigFuer.setSelected(true);
                    cbxGueltigFuer.setSelectedItem(ausgewaehlt);
                }
            } else {
                chbGueltigFuer.setSelected(true);
            }
        } else {
            chbGueltigFuer.setSelected(false);
            chbGueltigFuer.setEnabled(false);
        }

        /**
         * Speichern-Button hinzufügen.
         */
        buttonSpeichern = new JButton("Speichern");
        buttonSpeichern.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                if (!txtTitel.getText().equals("") &&
                        !txtTitel.getText().equals(STR_TITEL)) {

                    Alarm a = null;

                    if (alarm == null) {
                        a = ic.erstelleAlarm(
                                berechneTimestamp(spnStart.getValue()),
                                txtTitel.getText(),
                                ermittleKategorieId(),
                                ermittleErstellerId(),
                                ermittleKalenderId(),
                                ermittleGueltigFuerId());
                    } else {
                        a = ic.bearbeiteAlarm(alarm,
                                berechneTimestamp(spnStart.getValue()),
                                txtTitel.getText(),
                                ermittleKategorieId(),
                                ermittleErstellerId(),
                                ermittleKalenderId(),
                                ermittleGueltigFuerId());
                    }

                    hauptFenster.erstelleAlarmeVerwaltung();
                    SwingUtilities.updateComponentTreeUI(hauptFenster);
                    setVisible(false);
                    dispose();
                    try {
                        hauptFenster.setzteListIndex(a.
                                ermittleIdentifikationsName());
                        hauptFenster.initialisiereTimer();
                        JOptionPane.showMessageDialog(hauptFenster, "Alarm '" +
                                a.getTitel() +
                                "' erfolgreich gespeichert!");
                    } catch (RemoteException ex) {
                        Logger.getLogger(InterfaceClient.class.getName()).log(
                                Level.SEVERE, null, ex);
                    }
                }
            }
        });

        c.gridx = 1;
        c.gridy = 11;
        c.gridwidth = 2;
        hauptPanel.add(buttonSpeichern, c);

        return hauptPanel;
    }

    /**
     * erstellt das Textfield
     *
     * @return  JTextField   textFeld
     */
    public JTextField erstelleTextFeld(String platzhalter) {
        JTextField textFeld = new JTextField();

        if (alarm == null) {
            textFeld.setText(platzhalter);
        } else {
            try {
                if (platzhalter.equals(STR_TITEL)) {
                    textFeld.setText(alarm.getTitel());
                }
            } catch (RemoteException ex) {
                Logger.getLogger(DialogAlarm.class.getName()).log(Level.SEVERE,
                        null, ex);
            }
        }

        textFeld.addFocusListener(new TextFeldFocusListener(platzhalter, true));

        return textFeld;
    }

    /**
     *
     * erstellt den JSpinner und setzt das gewünscht Eingabeformat
     *
     * @return  JSpinner    spinner
     */
    private JSpinner erstelleDateSpinner() {
        JSpinner spinner = new JSpinner(new SpinnerDateModel());
        spinner.setEditor(new JSpinner.DateEditor(spinner,
                "dd.MM.yyyy HH:mm"));
        Timestamp jetzt = new Timestamp(Calendar.getInstance().getTime().
                getTime());

        if (alarm == null) {
            spinner.setValue(jetzt);
        } else {
            try {
                spinner.setValue(alarm.getStart());
            } catch (RemoteException ex) {
                Logger.getLogger(DialogAlarm.class.getName()).
                        log(Level.SEVERE, null, ex);
            }
        }
        return spinner;
    }

    /**
     * Ermittelt die Id des Ersteller
     * Unterscheidet sich je nachdem, ob Nutzer oder Administrator eingeloggt
     * ist.
     *
     * @return  int Ersteller-Id
     */
    private int ermittleErstellerId() {
        try {
            if (aktuellerNutzer == null) {
                // Admin-Ansicht. Ersteller in Form gewählt.
                return hashMapErsteller.get(cbxErsteller.getSelectedItem().
                        toString()).getPersonId();

            } else {
                // Nutzer angemeldet => Dessen ID.
                return aktuellerNutzer.getPersonId();
            }
        } catch (RemoteException ex) {
            Logger.getLogger(DialogTermin.class.getName()).
                    log(Level.SEVERE, null, ex);
        }

        return 0;
    }

    /**
     * Liest die ausgewählte Kategorie aus der Combox-Box aus und gibt
     * die zugehörige Id zurück.
     *
     * @return  int Id der gewählten Kategorie
     */
    private int ermittleKategorieId() {
        try {
            return hashMapKategorie.get(cbxKategorie.getSelectedItem().
                    toString()).getKategorieId();
        } catch (RemoteException ex) {
            Logger.getLogger(DialogTermin.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return 0;
    }

    /**
     * Liest den ausgewählten Kalender aus der Combox-Box aus und gibt
     * die zugehörige Id zurück.
     *
     * @return  int Id des gewählten Kalenders
     */
    private int ermittleKalenderId() {
        try {
            return hashMapKalender.get(cbxKalender.getSelectedItem().toString()).
                    getKalenderId();
        } catch (RemoteException ex) {
            Logger.getLogger(DialogTermin.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return 0;
    }

    /**
     * ermittelt die Id des Zugehörigen Termins
     * 
     * @return  int gueltigFuer
     */
    private int ermittleGueltigFuerId() {
        try {
            if (chbGueltigFuer.isSelected()) {
                return hashMapGueltigFuer.get(cbxGueltigFuer.getSelectedItem().
                        toString()).getId();
            }
        } catch (RemoteException ex) {
            Logger.getLogger(DialogAlarm.class.getName()).
                    log(Level.SEVERE, null, ex);
        }
        return 0;
    }

    /**
     * Berechnet anhand des übergebenen Combo-Box Items,
     * den Timestamp des Datums mit Hilfe der Calendar-Klasse.
     *
     * @param   o           Inhalt des Datum-JSpinner.
     * @return  Timestamp   berechnetes Timestamp-Objekt.
     */
    private Timestamp berechneTimestamp(Object o) {
        Calendar c = Calendar.getInstance();
        c.setTime((Date) o);
        return new Timestamp(c.getTime().getTime());
    }
}
